%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%  版权归杜文亮所有。                                       %%
%%  本作品采用 Creative Commons 署名-非商业性使用-相同方式共享 4.0 国际许可协议授权 %%
%%  要查看此许可证，请访问                           %%
%%  http://creativecommons.org/licenses/by-nc-sa/4.0/.              %%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\newcommand{\commonfolder}{../../common-files}

\input{\commonfolder/header}
\input{\commonfolder/copyright}
\hypersetup{%
    pdfborder = {0 0 0}
}

\lhead{\bfseries SEED Labs -- DNS基础架构}
\newcommand{\dnsFigs}{./Figs}


\usepackage{hyperref}

\begin{document}


\begin{center}
{\LARGE DNS基础架构实验}
\end{center}

\seedlabcopyright{2021}



% *******************************************
% SECTION
% ******************************************* 
\section{概述}

DNS（域名系统，Domain Name System）是互联网的电话簿；
它将主机名转换为IP地址（反之亦然）。这种转换过程通过DNS系统在幕后自动完成。
解析过程涉及许多名称服务器，包括根服务器、顶级域（Top-Level Domain, TLD）服务器和最终域服务器。
这些名称服务器共同构成了整个DNS基础架构，它们确保了互联网上所有设备之间的通信顺畅无阻。

为了帮助学生理解这些名称服务器如何协同工作以形成该基础设施，我们将在一个互联网模拟器中创建一个小规模的DNS系统。
虽然这个小规模的系统很小，但它拥有真实DNS基础设施的所有必要元素。通过建立这样一个系统，学生们将对DNS的实际运作有更深的理解。
虽然本实验不是安全实验的一部分，但它是几个SEED实验的基础。本实验涵盖以下主题：

\begin{itemize}[noitemsep]
\item DNS基础架构
\item DNS正向和反向查找过程
\item 根服务器和顶级域（Top-Level Domain, TLD）服务器
\item DNS解析器、本地DNS服务器
\end{itemize}

\paragraph{阅读材料与视频。}
关于DNS协议的详细内容可以在以下资源中找到：

\begin{itemize}
\item SEED书籍第23章，\seedcibook
\item SEED书籍第10章，\seedisbook
\item SEED讲义第七部分，\seedisvideo
\end{itemize}

\paragraph{实验环境。}
\seedenvironmentB
\nodependency

\paragraph{实验任务概述。}
DNS基础设施涉及许多服务器。我们将在一个模拟器中构建简化后的DNS基础架构。
这个基础设施包括两个根服务器、两个 \texttt{com} TLD (Top-Level Domain) 服务器，
一个 \texttt{edu} TLD 服务器以及两个二级域名名称服务器
(见图~\ref{dns:fig:dns-infrastructure})。
注意学生需要将 \texttt{smith2021} 替换为自己的姓氏和当前年份

\begin{figure}[htb]
\centering
\includegraphics[width=0.7\textwidth]{\dnsFigs/dns_infrastructure.pdf}
\caption{简化后的DNS基础架构}
\label{dns:fig:dns-infrastructure}
\end{figure}

我们需要为图中所示的每个区域配置名称服务器。我们将从底部向上进行配置。
具体来说，首先配置二级域名名称服务器（任务一：配置二级域名服务器），
然后是TLD服务器（任务二：配置顶级域服务器），接着是根服务器（任务三：配置根服务器）。
我们还需要配置本地DNS服务器和客户端机器（任务四和五），这样客户端就可以使用这个DNS系统了。
任务六是完善支持反向解析功能的DNS系统。


% -------------------------------------------
% SUBSECTION
% -------------------------------------------
\section{实验设置与SEED Internet仿真器}

本实验将在SEED Internet仿真器内进行（本文档中简称“仿真器”）。如果这是您第一次使用仿真器，那么阅读本节非常重要。
我们建议教师提供一个实验室课程来帮助学生熟悉仿真器。


% -------------------------------------------
% SUBSECTION
% -------------------------------------------
\subsection{Internet仿真器} 


\input{../../common-files/emulator/setup.tex}



% -------------------------------------------
% SUBSECTION
% -------------------------------------------
\subsection{仿真的Internet地图}

\input{../../common-files/emulator/map.tex}



% -------------------------------------------
% SUBSECTION
% -------------------------------------------
\subsection{过滤和回复}
 
\input{../../common-files/emulator/filter_and_replay.tex}


% -------------------------------------------
% SUBSECTION
% -------------------------------------------
\subsection{所有的名称服务器}

在这个仿真器中，DNS基础设施由多个运行DNS名称服务器的容器组成。
我们已经自定义了它们的容器名，以便于查找。所有容器的名字都包含术语 \texttt{DNS} ，并且他们的IP地址也包含在名字里。
以下命令可以列出所有的这些容器（为了显示目的重新排列了顺序）。

\begin{lstlisting}
$ dockps | grep DNS
dedc6676421e  as150h-DNS-Root-A-10.150.0.72
de5dc343224f  as160h-DNS-Root-B-10.160.0.72
84cf7c7f337d  as151h-DNS-COM-A-10.151.0.72
20c134dceee4  as161h-DNS-COM-B-10.161.0.72
f20fe7ed115f  as152h-DNS-EDU-10.152.0.71
cfabce676bed  as154h-DNS-Example-10.154.0.71
5801404d45d2  as162h-DNS-AAAAA-10.162.0.72
c357ff76bda6  as153h-Global_DNS-1-10.153.0.53
d65e76c44437  as163h-Global_DNS-2-10.163.0.53

// Get a shell on a selected container
$ docksh cfab   (*@\pointleft{container ID}@*) 
root@cfabce676bed / #
root@cfabce676bed / # st Example    (*@\pointleft{change the terminal title}@*)
\end{lstlisting}




% -------------------------------------------
% SUBSECTION
% -------------------------------------------
\subsection{复制DNS区域文件} 

在这个实验中，我们需要修改几个容器内的DNS区域文件（以及一些配置文件）。我们可以在这些容器内进行修改。
问题是，一旦容器停止并删除后，那些更改就会丢失。
最好将这些文件复制到主机上，在主机上进行修改后再将其复制回容器。我们可以使用\texttt{"docker cp"}命令来完成此操作。
由于我们需要频繁运行此命令，所以编写了以下Shell脚本，一个用于从容器获取区域文件到主机，另一个用于将区域文件复制回容器。
这两个文件都包含在实验设置文件夹中。

\begin{lstlisting}[caption=从容器获取区域文件: \texttt{getzone.sh}]
#!/bin/bash

keyword=$1   # Command-line argument 1: used to identify container
filename=$2  # Command-line argument 2: zone file name on container
filename_to=${keyword}_${filename}                                  (*@\lineone@*)
containerID=$(docker ps | grep $keyword | awk '{print $1}')         (*@\linetwo@*) 
if [[ ! -f $filename_to ]]; then
   docker cp $containerID:/etc/bind/zones/$filename ./$filename_to  (*@\linethree@*) 
else
   echo "** File $filename_to already exists; will not overwrite."
fi
\end{lstlisting}

在仿真器中，区域文件存储在 \texttt{/etc/bind/zones} 文件夹内。
每个DNS名称服务器的容器名中有唯一的关键词，
例如，处理 \texttt{example.com} 区域的名称服务器其容器名中含有关键词 \texttt{Example}。
通过使用此关键词，我们可以找到对应容器的唯一标识符（见行～\linetwo）。
同时在区域文件名前添加该关键词，以便于一旦复制到主机上时能够轻松识别它们（见行~\lineone 和~\linethree）。
以下示例演示了如何从两个根名称服务器和 \texttt{example.com} 名称服务器获取区域文件。


\begin{lstlisting}
$ ./getzone.sh Root-A root           (*@\pointleft{}@*) New file: Root-A_root
$ ./getzone.sh Root-B root           (*@\pointleft{}@*) New file: Root-B_root
$ ./getzone.sh Example example.com.  (*@\pointleft{}@*) New file: Example_example.com
\end{lstlisting}
 

将文件复制回容器的过程类似，只是在区域文件被复制后需要重启名称服务器（见行~\linefour）。

\begin{lstlisting}[caption=向容器发送区域文件: \texttt{sendzone.sh}]
#!/bin/bash

keyword=$1   # Command-line argument 1: used to identify container
filename=$2  # Command-line argument 2: zone file name on container
filename_from=${keyword}_${filename}
containerID=$(docker ps | grep $keyword | awk '{print $1}')
if [[ -f $filename_from ]]; then
   echo "== Copy zone file to container"
   docker cp ./$filename_from $containerID:/etc/bind/zones/$filename

   echo "== Restart the nameserver"
   docker exec $containerID service named restart      (*@\linefour@*) 
else
   echo "** File $filename_from does not exists."
fi
\end{lstlisting}
 
下面是使用 \texttt{sendzone.sh} 的示例。
它将Root-A的区域文件（\texttt{Root-A\_root}）发送回Root-A容器，并重启名称服务器。

\begin{lstlisting}
$ ./sendzone.sh Root-A root
== Copy zone file to container
== Restart the nameserver
  * Stopping domain name service... named
waiting for pid 92 to die
    ...done.
  * Starting domain name service... named
    ...done.
\end{lstlisting}




% *******************************************
% SECTION
% *******************************************
\section{任务1：配置域名服务器}
\label{dns-inf:sec:task1}

在这个任务中，我们将为两个域配置名称服务器，
一个是 \texttt{example.com} ，另一个是基于学生姓名自定义的名称。

% -------------------------------------------
% SUBSECTION
% -------------------------------------------
\subsection{任务 1.a：配置 \texttt{example.com} 的名称服务器}
 
在这个任务中，我们需要在仿真器内一个容器中的域名 \texttt{example.com} 上配置名称服务器。
该容器名包含关键词 \texttt{Example} ，以及 IP 地址。
 
\begin{lstlisting}
$ dockps | grep Example
46ab89e26738  as154h-DNS-Example-10.154.0.71
\end{lstlisting}

\paragraph{步骤1：添加区域条目。} 
要为 \texttt{example.com} 域托管服务器，我们需要在BIND的配置中添加一个区域条目，
以便它知道将要托管哪些区域。
在仿真器中，名称服务器托管的区域位于路径 \path{/etc/bind/named.conf.zones} 文件内（可以有多个区域）。
以下是一个示例，在此示例中，\texttt{file} 条目指定了包含实际区域信息的实际文件。
如果我们想在此名称服务器上托管另一个区域，可以在该文件中添加相应的区域条目。

\begin{lstlisting}
zone "example.com" { 
    type master;        (*@\pointleft{this is the master server}@*) 
    allow-update { any; }; 
    file "/etc/bind/zones/example.com.";  (*@\pointleft{the actual zone file}@*) 
};

zone "example.net" {
    ... 
}
\end{lstlisting}

上面 \texttt{example.com} 的区域条目表示当前名称服务器是该域名的主服务器，
并且在 \texttt{file} 条目中指定了实际的区域文件。
在仿真器中，区域文件位于路径 \path{/etc/bind/zones} 文件夹内。需要注意的是，
除了根区域外，大多数区域文件（filename）以点（.）结尾。这是本实验中需要修改的主要文件。

\paragraph{步骤2：修改区域文件。}
向区域文件添加至少四个记录（类型为 \texttt{A} ），以便将主机名映射到IP地址。
您可以使用星号 (\texttt{*}) 作为通配符主机名。


\begin{lstlisting}
$TTL 300               (*@\pointleft{The default time to live: 300 seconds}@*) 
$ORIGIN example.com.   (*@\pointleft{The start of this zone file in the namespace}@*) 
@ SOA ns1.example.com. admin.example.com. (*@\textbf{1635647622}@*) 900 900 1800 60

@                  NS    ns1.example.com.
ns1.example.com.   A     10.154.0.71

www                A     10.154.0.72
abc                A     10.154.0.73 
\end{lstlisting}

区域文件必须指定权威主名称服务器的起始授权（SOA）记录，
包括该域名的权威主名称服务器名和负责管理该名称服务器的电子邮件地址。
SOA 记录还指定了一个过期时间参数列表（序列号、从属刷新周期、从属重试时间、从属过期时间和缓存记录的最大时间）。 
如果我们修改区域文件，应改变序列号 (SOA条目中的高亮数字)，以使更改可以同步到从服务器。

在区域文件中, 以全点字符（即句点）结尾的域名是完全限定的；而没有以句点结尾的则是相对于当前起点而言的。
例如，在上面的例子中，\texttt{ns1.example.com.} 是一个完整名称，
而 \texttt{www} 表示的是 \texttt{www.example.com}。

\paragraph{步骤3：重启名称服务器。}
每次修改BIND配置文件后, 我们都需要重新启动名称服务器以使更改生效。
如果配置文件有误，名称服务器将无法正常启动。

\begin{lstlisting}
# service named restart
 * Stopping domain name service... named                                                                 waiting for pid 92 to die
                                                                                                  [ OK ]
 * Starting domain name service... named
\end{lstlisting}

\paragraph{步骤4：测试。} 
由于我们还没有完成整个DNS基础设施的设置, 我们需要使用 \texttt{@10.154.0.71} 选项将我们的DNS查询直接发送到 \texttt{10.154.0.71}, 
这是我们在仿真器内 \texttt{example.com} 名称服务器的IP地址。
如果操作无误, 您可以得到您在区域文件中指定的IP地址。请报告您的观察结果。

\begin{lstlisting}
$ dig @10.154.0.71 www.example.com
... 
;; ANSWER SECTION:
xyz.example.com.    300    IN    A    (*@\textbf{1.2.3.6}@*)
...
\end{lstlisting}

% -------------------------------------------
% SUBSECTION
% -------------------------------------------
\subsection{任务1.b：配置另一个域的名称服务器}
 
在这个任务中，我们将为另一个域配置名称服务器。
该域名应采用以下格式 \texttt{<NAME><YEAR>.edu}，其中 \texttt{<NAME>} 应替换为您的姓氏，
而 \texttt{<YEAR>} 用当前年份替代。例如, 如果您的姓是 \texttt{Smith}, 当前的年份是2021年，则域名将是\texttt{smith2021.edu}。
在仿真器中，已创建了一个空名称服务器；
容器名包含关键词 \texttt{AAAAA} 请使用此名称服务器来托管您的域。

\begin{lstlisting}
$ dockps | grep AAAAA
70f2e8a57a96  as162h-DNS-AAAAA-10.162.0.72
\end{lstlisting}

% *******************************************
% SECTION
% *******************************************
\section{任务2：配置TLD服务器}
 
在这个任务中，我们将为两个TLD域名 \texttt{com} 和 \texttt{edu} 配置名称服务器。
我们已经创建了三个名称服务器来托管这两个TLD域名。

\begin{lstlisting}
$ dockps | grep DNS
c3040914667c  as151h-DNS-COM-A-10.151.0.72    (*@\pointleft{The master com server}@*) 
3fa8fa41afb6  as161h-DNS-COM-B-10.161.0.72    (*@\pointleft{The slave com server}@*)
6c7132feb7d4  as152h-DNS-EDU-10.152.0.71      (*@\pointleft{The edu server}@*)
...
\end{lstlisting}
 
TLD \texttt{com} 区域有两个名字服务器。一个配置为主服务器，另一个为从属服务器。
我们只需要修改主服务（COM-A）的区域文件, 因为从属服务器会自动与主服务器同步。
以下是在这两个服务器上的区域配置。

\begin{lstlisting}
// For master (COM-A)
zone "com." { type master; allow-transfer { any; }; ...};

// For slave (COM-B)
zone "com." { type slave; masters { 10.151.0.72; }; ... };
\end{lstlisting}


TLD域内的所有名称服务器都必须在该 TLD 服务器中注册它们的名称服务, 否则任何人都找不到它们。
对于每个域名，如 \texttt{example.com}，
需要向 TLD \texttt{com} 的区域文件添加两个条目：一个 \texttt{NS} 记录和一个\texttt{A}记录。
\texttt{NS} 记录指定 \texttt{example.com} 域名的名称服务器，\texttt{A} 记录指定名称服务器的 IP 地址。

\paragraph{实验任务。}
请将您的 \texttt{example.com} 和 \texttt{<NAME><YEAR>.edu} 名称服务器注册到其相应的 TLD 服务器。
记得在更改后运行\texttt {"service named restart"} 以重启名称服务器。
同时需要改变区域文件的序列号；否则，主服务器上的更改不会同步到从属服务器上。完成更改后，请执行以下命令测试服务并报告您的观察结果。

\begin{lstlisting}
# dig @10.151.0.72 www.example.com       (*@\pointleft{Query the COM-A server}@*) 
# dig @10.161.0.72 www.example.com       (*@\pointleft{Query the COM-B server}@*) 
# dig @10.152.0.72 www.<NAME><YEAR>.edu  (*@\pointleft{Query the EDU server}@*) 
\end{lstlisting}


需要注意的是，TLD 服务器被配置为不执行递归查询，
因此只会告诉您域名查询的名称服务器；它不会为您解析该查询。
见下方配置。

\begin{lstlisting}
// File: named.conf.options
options {
        directory "/var/cache/bind";
        (*@\textbf{recursion no;}@*)  
        dnssec-validation no;
        empty-zones-enable no;
        allow-query { any; };
        allow-update { any; };
};
\end{lstlisting}

% *******************************************
% SECTION
% *******************************************
\section{任务3：配置根服务器}
 
在这个任务中，我们将为根区域配置名称服务器。
在现实世界中，有13个给根区的名称服务器，
它们通过IANA维护的根区域文件进行同步。 在我们的仿真器里，我们创建了两个根服务器，并且其容器名包含关键词 \texttt{Root} 。
我们将通过将相同的文件内容放入它们的区域文件中来手动使它们同步。

\begin{lstlisting}
$ dockps | grep Root
9a96092c7c85  as150h-DNS-Root-A-10.150.0.72
60f171f92287  as160h-DNS-Root-B-10.160.0.72
\end{lstlisting}
 

所有TLD名称服务器都需要注册到根服务器，以便在DNS查询过程中能够找到它们。
对于每一个我们想包含在微型DNS系统中的 TLD 区域，
我们需要在其区域文件中至少添加两个记录，包括一个 \texttt{NS} 记录和一个 \texttt{A} 记录。
在此任务中，学生需要修改这两个根服务器的区域文件以支持仿真器中的\texttt{com} 和\texttt{edu} TLDs。
区域文件位于路径 \path{/etc/bind/zones} 文件夹内。
在完成更改后，请重启两个名称服务器，并从另一个容器执行以下命令（用根服务器IP地址替换\texttt{<root-ip>}；请尝试两个根服务器）。 
报告并解释您的观察结果。

\begin{lstlisting}
$ dig @<root-ip>    <ANYNAME>.com   (*@\pointleft{choose an arbitrary name}@*) 
$ dig @<root-ip>    <ANYNAME>.edu
$ dig @<root-ip>    com
$ dig @<root-ip>    edu
\end{lstlisting}

% *******************************************
% SECTION
% *******************************************
\section{任务4：配置本地DNS服务器}
 
当计算机需要从主机名解析IP地址（反之亦然）时，它会向其助手发送请求，该助手被称为本地DNS服务器或DNS解析器。
这个DNS解析器将进行整个DNS解析过程，并然后将结果返回给计算机。尽管称之为“本地”，但此服务器并不一定位于本地位置。
在过去，当设置计算机时，通常使用自己的本地网络上的DNS服务器，
但现在，有许多非本地的DNS服务器可以作为“本地”DNS服务器来使用。
例如，Google公共DNS\index{Google Public DNS}就是由Google提供的一项DNS服务，可供Internet上任何主机使用。

当我们配置根、TLD和域名服务器时，我们将其设置为非递归的，即它们只会告诉您他们所知道的信息，而不会进行整个解析过程以获取最终答案。
当我们将本地DNS服务器配置为开启递归选项（如下所示），它会为您获取答案。

\begin{lstlisting}
options {
    recursion yes;
    ...
};
\end{lstlisting}

如果本地DNS服务器在缓存中找不到答案，它将通过迭代过程从外部名称服务器获取答案。 
这个过程从根服务器开始。
因此，本地DNS服务器需要知道根服务器的IP地址。

在路径 \path{/etc/bind/named.conf.default-zones} 文件内（包含于BIRD配置文件 \path{/etc/bind/named.conf} 中）
有一个为根区域设置的条目。这个条目指定了一个根区域的提示文件，这就是使本地DNS服务器知道根服务器IP地址的源头。

\begin{lstlisting}
zone "." {
    type hint;
    file "/usr/share/dns/root.hints";
};
\end{lstlisting}

在现实世界中，有13个给根区的名称服务器，
因此它们的IP地址被提供在 \texttt{root.hints} 文件内。
在我们的仿真器里，我们只有两个根服务器。他们的信息已经添加到提示文件内。

\begin{lstlisting}
.      NS   ns1.
.      NS   ns2.
ns1.   A    10.150.0.72
ns2.   A    10.160.0.72
\end{lstlisting}

\paragraph{任务。} 我们在仿真器内创建了两个DNS解析器。
我们已经在仿真的容器名中加入了关键词 \texttt{Global\_DNS} 并且包含了解析器的 IP 地址。
您可以使用以下命令找到这两个DNS解析器。

\begin{lstlisting}
$ dockps | grep Global_DNS
c357ff76bda6  as153h-Global_DNS-1-10.153.0.53
d65e76c44437  as163h-Global_DNS-2-10.163.0.53
\end{lstlisting}

请到他们的 \texttt{root.hints} 文件。
在文件内，请将根名称服务器的IP地址更改其它地址（例如，把72改成75），然后展示这如何影响DNS解析过程（执行以下命令）。
请报告并解释您的观察结果。 
请记得完成此任务后将其改回，因为后续的任务依赖于它们。

\begin{lstlisting}
# dig @10.153.0.53  example.com
# dig @10.163.0.53  example.com
\end{lstlisting}



% *******************************************
% SECTION
% *******************************************
\section{任务5：配置客户端} 

到目前为止，我们需要在我们的 \texttt{dig} 命令中使用 \texttt{@<ip>} 来指示 dig 命令应该与哪个DNS服务器通信。
虽然这对 dig 命令不是问题, 但对于依赖于 DNS 的其他软件来说这是一个问题。
我们需要告诉操作系统它应该使用哪个DNS服务器。
我们可以通过在用户的机器上更新解析器的配置文件 \texttt{/etc/resolv.conf} 文件来指示操作系统使用特定的本地DNS解析器。
在文件的第一个 \texttt{nameserver} 条目里填入容器的IP地址，即该服务器将作为主要的DNS解析器。

我们已经配置了所有机器使用 \texttt{10.153.0.53} 作为主要 DNS 解析器，
除了属于 AS-155 的机器。
你的任务是配置 AS-155 中的主机，使它们能够使用其中一个（或两个）DNS解析器。
你可以在 \texttt{/etc/resolv.conf} 文件中添加如下条目之一（或两个）：

\begin{lstlisting}
nameserver 10.153.0.53
nameserver 10.163.0.53
\end{lstlisting}


\paragraph{测试整个DNS基础设施。}
此时，DNS 基础设施已经完全设置好，
我们可以运行 \texttt{dig} 而不使用 \texttt{@<ip>} 选项；
\texttt{dig} 将使用系统设置的本地 DNS 服务器。请从 AS-155 中的一个主机上执行以下命令。
如果一切配置正确，你应该能够得到预期的答案。

\begin{lstlisting}
# dig www.example.com
# dig <NAME><YEAR>.edu 
\end{lstlisting}

请使用地图显示数据包跟踪情况。
首先设置过滤器为 \texttt{"udp and dst port 53"} 来捕获 DNS 请求流量。然后执行这些 \texttt{dig} 命令。
如果整个过程发生得太快，你可以使用地图的重播功能：在设置好过滤器后，
点击记录按钮，再执行上述 \texttt{dig} 命令。停止录制并播放所录制的事件。
如有必要，请调整时间间隔。
因为截取数据包追踪的屏幕截图有些困难，所以在报告中描述数据包追踪情况就足够了。

% *******************************************
% SECTION
% *******************************************

\section{任务6：反向DNS查找}

反向 DNS 查找是从 IP 地址找出主机名的过程。这一过程实际上与正向查找非常相似。
我们用一个例子来说明此过程。给定一个 IP 地址，例如 \texttt{128.230.171.184} 这个 IP 地址属于 \texttt{syr.edu}，
DNS 解析器构造了一个“伪造”的名称\texttt{184.171.230.128.in-addr.arpa}，然后通过一个迭代过程发送查询请求，
就像正向查找一样。也就是说，它从根服务器开始，到 \texttt{in-addr.arpa} 服务器、
\texttt{128.in-addr.arpa} 服务器，最终到达托管 \texttt{syr.edu} 区域的 \texttt{230.128.in-addr.arpa} 服务器。

任务 1 到 4 只设置了正向查找所需的 DNS 基础设施。
在这项任务中，我们将设置反向查找所需的基础设施。
出于简化的考量，我们仅支持仿真器中的 \texttt{example.com} 域 IP 地址的反向查询
（即，在 \texttt{10.154.0.0/24} 网络中的IP地址）。
你需要设置以下名称服务器：

\begin{itemize}
\item 步骤 1：配置根服务器。
根服务器需要托管 \texttt{in-addr.arpa} 域的NS记录。
我们需要在两台根服务器的 \texttt{/etc/bind/zones/root} 文件里分别添加相应的名称服务器记录。

\item 步骤2：设置\texttt{in-addr.arpa}服务器。
该服务器应托管\texttt{in-addr.arpa.}区域。
我们可以使用\texttt{com}域名服务器来托管这个区域，通过在\path{/etc/bind/named.conf.zones}文件中添加该区域实现。
一个域名服务器可以同时托管多个不同的区域。

\begin{lstlisting}
zone "com." {
        ... already there ...
};

zone "in-addr.arpa." {
        type master;
        notify yes;
        allow-transfer { any; };
        allow-update { any; };
        file "/etc/bind/zones/in-addr.arpa.";  (*@\pointleft{the zone file}@*) 
};
\end{lstlisting}


我们需要创建上述条目中指定的区域文件\texttt{in-addr.arpa.}。
我们在该区域文件中添加\texttt{154.10.in-addr.arpa} 区域的NS记录。
为了简化，我们直接为\texttt{154.10}子区域提供NS记录，
而不是只为\texttt{10.in-addr.arpa} 区域提供NS记录（然后，
依赖\texttt{10.in-addr.arpa} 服务器来提供\texttt{154.10} 子区域的信息）。
下面是一个简化的区域文件示例：

\begin{lstlisting}
$TTL 300
$ORIGIN in-addr.arpa.

@        SOA ns1.com. admin.com. 1565237345 900 900 1800 60
@        NS  ns1.com.
@        NS  ns2.com.
ns1.com. A 10.151.0.72
ns2.com. A 10.161.0.72

; Please replace ____ with the correct information
154.10.in-addr.arpa.  NS  ____   (*@\pointleft{The nameserver of the domain}@*) 
____                  A   ____   (*@\pointleft{The IP address of the nameserver}@*)
\end{lstlisting}


\item 步骤 3：配置\texttt{154.10.in-addr.arpa}服务器：
此域名服务器可以在托管\texttt{example.com}区域的同一域名服务器上运行。
我们应该在其\texttt{/etc/bind/named.conf.zones}文件中添加一个区域条目（类似于步骤2），然后
创建相应的区域文件，该文件应包含\texttt{example.com}域的逆向解析记录。
以下是一个可能的区域文件示例：

\begin{lstlisting}
$TTL 300

$ORIGIN 154.10.in-addr.arpa.
@ SOA ns1.example.com. admin.example.com. 1635647622 900 900 1800 60

@                NS ns1.example.com.
ns1.example.com. A  10.154.0.71

71.0     IN      PTR     ns1.example.com.
72.0     IN      PTR     www.example.com.
73.0     IN      PTR     abc.example.com.
\end{lstlisting}

\end{itemize}

\paragraph{测试。} 在对名称服务器进行修改后，
请确保运行 \texttt{"service named restart"} 来重启 DNS 服务器。
如果一切设置正确，我们可以到模拟器中的任意主机上运行以下反向查询命令。
请记录并说明您的观察结果。请使用map展示其中一个命令的数据包路径，
并在报告中描述该数据包路径。

\begin{lstlisting}
dig -x 10.154.0.71
dig -x 10.154.0.72
dig -x 10.154.0.73
\end{lstlisting}

% *******************************************
% SECTION
% ******************************************* 
\section{提交}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\input{\commonfolder/submission}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%



% *******************************************
% SECTION
% ******************************************* 
\section*{致谢} 

本实验室得到了Honghao Zeng和Keyi Li的帮助，他们在SEED Internet仿真器的DNS模块开发中做出了贡献。 
本实验的部分经费来自于美国国家科学基金以及雪城大学的赞助。
\end{document}